/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.meta.service.impl;

import cn.hutool.core.date.DateUtil;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.je.common.base.DynaBean;
import com.je.common.base.exception.PlatformException;
import com.je.common.base.exception.PlatformExceptionEnum;
import com.je.common.base.mapper.query.NativeQuery;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaResourceService;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.util.JEUUID;
import com.je.common.base.util.SecurityUserHolder;
import com.je.ibatis.extension.metadata.IdType;
import com.je.meta.service.SqlTemplateService;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.update.Update;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class SqlTemplateServiceImpl implements SqlTemplateService {

    private static final Logger logger = LoggerFactory.getLogger(SqlTemplateServiceImpl.class);

    private static final Pattern paramsPattern = Pattern.compile("\\{[a-zA-Z][a-zA-Z0-9_]*}|'\\{[a-zA-Z][a-zA-Z0-9_]*}'");
    private static final Pattern questionMarkPattern = Pattern.compile("\\?");

    @Autowired
    private MetaService metaService;
    @Autowired
    private MetaResourceService metaResourceService;
    @Autowired
    private BeanService beanService;
    @Autowired
    private CommonService commonService;

    private void formatBackendEntryType(String entryType, String entryName) {
        if (!Strings.isNullOrEmpty(entryType)) {
            return;
        }
        entryType = "JAVA";
        entryName = "后台触发";
    }

    @Override
    @Transactional
    public int insert(String entryType, String entryName, String entryDesc, String projectCode, String templateCode, Map<String, Object> params) throws JSQLParserException {
        formatBackendEntryType(entryType, entryName);
        DynaBean templateBean = metaResourceService.selectOneByNativeQuery("JE_CORE_QJSQL", NativeQuery.build()
                .eq("QJSQL_PROJECT_CODE", projectCode)
                .eq("QJSQL_MBBM", templateCode));
        if (templateBean == null) {
            return 0;
        }
        if (!"1".equals(templateBean.getStr("QJSQL_QY_CODE"))) {
            throw new PlatformException("此模板已禁用！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        String templateContent = templateBean.getStr("QJSQL_MBNR");
        if (Strings.isNullOrEmpty(templateContent)) {
            return 0;
        } else {
            templateContent = templateContent.replaceAll("\\--.*", "");
        }

        if (!"Insert".equals(templateBean.getStr("QJSQL_SQLJBZXCL_CODE"))) {
            throw new PlatformException("SQL模板错误，请正确使用SQL模板！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        if (!checkInsert(templateContent)) {
            throw new PlatformException("非法的SQL模板，请正确使用SQL模板！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        logger.info("The user {} use the insert template {},the template sql is {}", SecurityUserHolder.getCurrentAccountId(), templateCode, templateContent);
        return executeInsert(entryType, entryName, entryDesc, templateBean.getStr("JE_CORE_QJSQL_ID"), templateContent, params, false);

    }

    @Override
    public int insertAndInit(String entryType, String entryName, String entryDesc, String projectCode, String templateCode, Map<String, Object> params) throws JSQLParserException {
        formatBackendEntryType(entryType, entryName);
        DynaBean templateBean = metaResourceService.selectOneByNativeQuery("JE_CORE_QJSQL", NativeQuery.build()
                .eq("QJSQL_PROJECT_CODE", projectCode)
                .eq("QJSQL_MBBM", templateCode));
        if (templateBean == null) {
            return 0;
        }
        if (!"1".equals(templateBean.getStr("QJSQL_QY_CODE"))) {
            throw new PlatformException("此模板已禁用！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        String templateContent = templateBean.getStr("QJSQL_MBNR");
        if (Strings.isNullOrEmpty(templateContent)) {
            return 0;
        } else {
            templateContent = templateContent.replaceAll("\\--.*", "");
        }

        if (!"InsertAndInit".equals(templateBean.getStr("QJSQL_SQLJBZXCL_CODE"))) {
            throw new PlatformException("SQL模板错误，请正确使用SQL模板！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        if (!checkInsert(templateContent)) {
            throw new PlatformException("非法的SQL模板，请正确使用SQL模板！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        logger.info("The user {} use the insertAndInit template {},the template sql is {}", SecurityUserHolder.getCurrentAccountId(), templateCode, templateContent);
        return executeInsert(entryType, entryName, entryDesc, templateBean.getStr("JE_CORE_QJSQL_ID"), templateContent, params, true);
    }

    @Override
    @Transactional
    public int update(String entryType, String entryName, String entryDesc, String projectCode, String templateCode, Map<String, Object> params) throws JSQLParserException {
        formatBackendEntryType(entryType, entryName);
        DynaBean templateBean = metaResourceService.selectOneByNativeQuery("JE_CORE_QJSQL", NativeQuery.build()
                .eq("QJSQL_PROJECT_CODE", projectCode)
                .eq("QJSQL_MBBM", templateCode));
        if (templateBean == null) {
            return 0;
        }
        if (!"1".equals(templateBean.getStr("QJSQL_QY_CODE"))) {
            throw new PlatformException("此模板已禁用！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        String templateContent = templateBean.getStr("QJSQL_MBNR");
        if (Strings.isNullOrEmpty(templateContent)) {
            return 0;
        } else {
            templateContent = templateContent.replaceAll("\\--.*", "");
        }

        if (!"Update".equals(templateBean.getStr("QJSQL_SQLJBZXCL_CODE"))) {
            throw new PlatformException("SQL模板错误，请正确使用SQL模板！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        if (!checkUpdate(templateContent)) {
            throw new PlatformException("非法的SQL模板，请正确使用SQL模板！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        logger.info("The user {} use the update template {},the template sql is {}", SecurityUserHolder.getCurrentAccountId(), templateCode, templateContent);
        return executeUpdate(entryType, entryName, entryDesc, templateBean.getStr("JE_CORE_QJSQL_ID"), templateContent, params);
    }

    @Override
    @Transactional
    public int delete(String entryType, String entryName, String entryDesc, String projectCode, String templateCode, Map<String, Object> params) throws JSQLParserException {
        formatBackendEntryType(entryType, entryName);
        DynaBean templateBean = metaResourceService.selectOneByNativeQuery("JE_CORE_QJSQL", NativeQuery.build()
                .eq("QJSQL_PROJECT_CODE", projectCode)
                .eq("QJSQL_MBBM", templateCode));
        if (templateBean == null) {
            return 0;
        }
        if (!"1".equals(templateBean.getStr("QJSQL_QY_CODE"))) {
            throw new PlatformException("此模板已禁用！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        String templateContent = templateBean.getStr("QJSQL_MBNR");
        if (Strings.isNullOrEmpty(templateContent)) {
            return 0;
        } else {
            templateContent = templateContent.replaceAll("\\--.*", "");
        }

        if (!"Delete".equals(templateBean.getStr("QJSQL_SQLJBZXCL_CODE"))) {
            throw new PlatformException("SQL模板错误，请正确使用SQL模板！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        if (!checkDelete(templateContent)) {
            throw new PlatformException("非法的SQL模板，请正确使用SQL模板！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        logger.info("The user {} use the delete template {},the template sql is {}", SecurityUserHolder.getCurrentAccountId(), templateCode, templateContent);
        return executeUpdate(entryType, entryName, entryDesc, templateBean.getStr("JE_CORE_QJSQL_ID"), templateContent, params);
    }

    @Override
    public List<Map<String, Object>> select(String entryType, String entryName, String entryDesc, String projectCode, String templateCode, Map<String, Object> params) throws JSQLParserException {
        formatBackendEntryType(entryType, entryName);
        DynaBean templateBean = metaResourceService.selectOneByNativeQuery("JE_CORE_QJSQL", NativeQuery.build()
                .eq("QJSQL_PROJECT_CODE", projectCode)
                .eq("QJSQL_MBBM", templateCode));
        if (templateBean == null) {
            return null;
        }
        if (!"1".equals(templateBean.getStr("QJSQL_QY_CODE"))) {
            throw new PlatformException("此模板已禁用！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        String templateContent = templateBean.getStr("QJSQL_MBNR");
        if (Strings.isNullOrEmpty(templateContent)) {
            return null;
        } else {
            templateContent = templateContent.replaceAll("\\--.*", "");
        }

        if (!"Select".equals(templateBean.getStr("QJSQL_SQLJBZXCL_CODE"))) {
            throw new PlatformException("SQL模板错误，请正确使用SQL模板！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        if (!checkSelect(templateContent)) {
            throw new PlatformException("非法的SQL模板，请正确使用SQL模板！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        logger.info("The user {} use the select template {},the template sql is {}", SecurityUserHolder.getCurrentAccountId(), templateCode, templateContent);

        TemplateReplaceSql replaceSql = replaceSqlParams(templateContent);
        Object[] paramsObjArr;
        if (replaceSql.getParamKeyList() == null) {
            paramsObjArr = new Object[0];
        } else {
            paramsObjArr = new Object[replaceSql.getParamKeyList().size()];
        }

        for (int j = 0; replaceSql.getParamKeyList() != null && j < replaceSql.getParamKeyList().size(); j++) {
            paramsObjArr[j] = params.get(replaceSql.getParamKeyList().get(j).getKey());
        }

        formatOutputSql(replaceSql,params);
        logger.debug("The User {} execute the select sql template,the final sql is {}", SecurityUserHolder.getCurrentAccountId(), replaceSql.getSql());
        try {
            List<Map<String, Object>> result = metaService.selectSql(replaceSql.getSql(), paramsObjArr);
            log(true, templateBean.getStr("JE_CORE_QJSQL_ID"), entryType, entryName, entryDesc, replaceSql.getOutputSql());
            return result;
        } catch (Throwable e) {
            e.printStackTrace();
            log(false, templateBean.getStr("JE_CORE_QJSQL_ID"), entryType, entryName, entryDesc, replaceSql.getOutputSql());
            throw new PlatformException(e);
        }
    }

    private void formatOutputSql(TemplateReplaceSql templateReplaceSql, Map<String, Object> params) {
        String outputSql = new String(templateReplaceSql.getSql());
        List<ParamKey> paramKeyList = templateReplaceSql.getParamKeyList();
        for (int i = 0; paramKeyList != null && i < paramKeyList.size(); i++) {
            outputSql = outputSql.replace("{" + i + "}", formatOutKeyValue(paramKeyList.get(i), params));
        }
        templateReplaceSql.setOutputSql(outputSql);
    }

    private String formatOutKeyValue(ParamKey paramKey, Map<String, Object> params) {
        Object value = params.get(paramKey.getKey());
        if ("string".equals(paramKey.getType())) {
            return "'" + value + "'";
        }
        return String.valueOf(value);
    }

    private int executeInsert(String entryType, String entryName, String entryDesc, String templateId, String sql, Map<String, Object> params, boolean isSetSystemDefaultValues) throws JSQLParserException {
        TemplateReplaceSql templateReplaceSql;
        if (isSetSystemDefaultValues) {
            templateReplaceSql = replaceInsertSqlParamsWithGenCreateInfo(sql);
        } else {
            templateReplaceSql = replaceInsertSqlParamsWithGenColumns(sql, null, null);
        }

        Object[] paramsObjArr;
        if (templateReplaceSql.getParamKeyList() == null) {
            paramsObjArr = new Object[0];
        } else {
            paramsObjArr = new Object[templateReplaceSql.getParamKeyList().size()];
        }
        for (int j = 0; templateReplaceSql.getParamKeyList() != null && j < templateReplaceSql.getParamKeyList().size(); j++) {
            paramsObjArr[j] = params.get(templateReplaceSql.getParamKeyList().get(j).getKey());
        }

        formatOutputSql(templateReplaceSql,params);
        logger.debug("The User {} execute the insert sql template,the final sql is {}", SecurityUserHolder.getCurrentAccountId(), templateReplaceSql.getSql());
        try {
            int result = metaService.executeSql(templateReplaceSql.getSql(), paramsObjArr);
            log(true, templateId, entryType, entryName, entryDesc, templateReplaceSql.getOutputSql());
            return result;
        } catch (Throwable e) {
            e.printStackTrace();
            log(false, templateId, entryType, entryName, entryDesc, templateReplaceSql.getOutputSql());
            throw new PlatformException(e);
        }

    }

    private int executeUpdate(String entryType, String entryName, String entryDesc, String templateId, String sql, Map<String, Object> params) {
        TemplateReplaceSql replaceSql = replaceSqlParams(sql);
        Object[] paramsObjArr;
        if (replaceSql.getParamKeyList() == null) {
            paramsObjArr = new Object[0];
        } else {
            paramsObjArr = new Object[replaceSql.getParamKeyList().size()];
        }
        for (int j = 0; replaceSql.getParamKeyList() != null && j < replaceSql.getParamKeyList().size(); j++) {
            paramsObjArr[j] = params.get(replaceSql.getParamKeyList().get(j).getKey());
        }

        formatOutputSql(replaceSql,params);
        logger.debug("The User {} execute the update or delete sql template,the final sql is {}", SecurityUserHolder.getCurrentAccountId(), replaceSql.getSql());
        try {
            int result = metaService.executeSql(replaceSql.getSql(), paramsObjArr);
            log(true, templateId, entryType, entryName, entryDesc, replaceSql.getOutputSql());
            return result;
        } catch (Throwable e) {
            e.printStackTrace();
            log(false, templateId, entryType, entryName, entryDesc, replaceSql.getOutputSql());
            throw new PlatformException(e);
        }
    }

    private TemplateReplaceSql replaceSqlParams(String sql) {
        Matcher paramsMatcher = paramsPattern.matcher(sql);
        StringBuffer sb = new StringBuffer();
        int i = 0;
        List<ParamKey> paramsKeyList = new ArrayList<>();
        String eachParam;
        ParamKey eachParamKey;
        while (paramsMatcher.find()) {
            paramsMatcher.appendReplacement(sb, "{" + i + "}");
            eachParam = sql.substring(paramsMatcher.start() + 1, paramsMatcher.end() - 1);
            if (eachParam.startsWith("{")) {
                eachParamKey = new ParamKey(sql.substring(paramsMatcher.start() + 2, paramsMatcher.end() - 2), "string");
            } else {
                eachParamKey = new ParamKey(sql.substring(paramsMatcher.start() + 1, paramsMatcher.end() - 1), "");
            }
            paramsKeyList.add(eachParamKey);
            i++;
        }
        paramsMatcher.appendTail(sb);
        return new TemplateReplaceSql(sb.toString(), paramsKeyList);
    }

    /**
     * 替换SQL参数，自动填充创建信息
     *
     * @param sql
     * @return
     */
    private TemplateReplaceSql replaceInsertSqlParamsWithGenCreateInfo(String sql) throws JSQLParserException {
        Column createUserIdColumn = new Column(null, "SY_CREATEUSERID");
        Column createUserNameColumn = new Column(null, "SY_CREATEUSERNAME");
        Column createOrgIdColumn = new Column(null, "SY_CREATEORGID");
        Column createOrgNameColumn = new Column(null, "SY_CREATEORGNAME");
        Column companyIdColumn = new Column(null, "SY_COMPANY_ID");
        Column companyNameColumn = new Column(null, "SY_COMPANY_NAME");
        Column groupCompanyIdColumn = new Column(null, "SY_GROUP_COMPANY_ID");
        Column groupCompayNameColumn = new Column(null, "SY_GROUP_COMPANY_NAME");
        Column orgIdColumn = new Column(null, "SY_ORG_ID");
        Column createTimeColumn = new Column(null, "SY_CREATETIME");
        List<Column> columnList = Lists.newArrayList(createUserIdColumn, createUserNameColumn,
                createOrgIdColumn, createOrgNameColumn,
                companyIdColumn, companyNameColumn,
                groupCompanyIdColumn,
                groupCompayNameColumn,
                orgIdColumn, createTimeColumn);
        List<Expression> expressionList = Lists.newArrayList(formatStringValue(SecurityUserHolder.getCurrentAccountRealUserId()),
                formatStringValue(SecurityUserHolder.getCurrentAccountRealUserName()),
                formatStringValue(SecurityUserHolder.getCurrentAccountRealOrgId()),
                formatStringValue(SecurityUserHolder.getCurrentAccountRealOrgName()),
                formatStringValue(SecurityUserHolder.getCurrentAccountDepartment() == null ? null : SecurityUserHolder.getCurrentAccountDepartment().getCompanyId()),
                formatStringValue(SecurityUserHolder.getCurrentAccountDepartment() == null ? null : SecurityUserHolder.getCurrentAccountDepartment().getCompanyName()),
                formatStringValue(SecurityUserHolder.getCurrentAccountDepartment() == null ? null : SecurityUserHolder.getCurrentAccountDepartment().getGroupCompanyId()),
                formatStringValue(SecurityUserHolder.getCurrentAccountDepartment() == null ? null : SecurityUserHolder.getCurrentAccountDepartment().getGroupCompanyName()),
                formatStringValue(SecurityUserHolder.getCurrentAccountOrg() == null ? null : SecurityUserHolder.getCurrentAccountOrg().getId()),
                formatStringValue(DateUtil.now()));
        return replaceInsertSqlParamsWithGenColumns(sql, columnList, expressionList);
    }

    /**
     * 增加字段
     *
     * @param sql
     * @param columns
     * @param expressionList
     * @return
     * @throws JSQLParserException
     */
    private TemplateReplaceSql replaceInsertSqlParamsWithGenColumns(String sql, List<Column> columns, List<Expression> expressionList) throws JSQLParserException {
        if (columns == null) {
            columns = new ArrayList<>();
        }
        if (expressionList == null) {
            expressionList = new ArrayList<>();
        }

        if (columns.size() != expressionList.size()) {
            throw new JSQLParserException("The added column size is not equal the value expression size!");
        }


        //替换参数"{param}"，否则转SQL语法树报错
        Matcher paramsMatcher = paramsPattern.matcher(sql);
        StringBuffer sb = new StringBuffer();
        List<ParamKey> paramsKeyList = new ArrayList<>();
        String eachParam;
        ParamKey eachParamKey;
        while (paramsMatcher.find()) {
            paramsMatcher.appendReplacement(sb, "?");
            eachParam = sql.substring(paramsMatcher.start() + 1, paramsMatcher.end() - 1);
            if (eachParam.startsWith("{")) {
                eachParamKey = new ParamKey(sql.substring(paramsMatcher.start() + 2, paramsMatcher.end() - 2), "string");
            } else {
                eachParamKey = new ParamKey(sql.substring(paramsMatcher.start() + 1, paramsMatcher.end() - 1), "");
            }
            paramsKeyList.add(eachParamKey);
        }
        paramsMatcher.appendTail(sb);

        Insert insert = (Insert) CCJSqlParserUtil.parse(sb.toString());
        if (insert.getSelect() != null) {
            return replaceSqlParams(sql);
        }

        Table table = insert.getTable();
        DynaBean tableBean = beanService.getResourceTable(table.getName());
        if (tableBean != null) {
            String tablePkField = tableBean.getStr("RESOURCETABLE_PKCODE");
            boolean flag = false;
            for (int i = 0; insert.getColumns() != null && i < insert.getColumns().size(); i++) {
                if (tablePkField.equals(insert.getColumns().get(i).getColumnName())) {
                    flag = true;
                    break;
                }
            }
            DynaBean resourceTable = metaResourceService.selectOneByNativeQuery("JE_CORE_RESOURCETABLE", NativeQuery.build().eq("RESOURCETABLE_TABLECODE", table.getName()));
            String generatorType = resourceTable.getStr("RESOURCETABLE_KEY_GENERATOR_TYPE");
            //如果不存在主键字段，表主键类型是UUID类型，则加入主键字段和值
            if (!flag) {
                if (Strings.isNullOrEmpty(generatorType) || IdType.UUID.getValue().equals(generatorType)) {
                    columns.add(new Column(null, tablePkField));
                    expressionList.add(new StringValue(JEUUID.uuid()));
                }
            }
        }

        insert.addColumns(columns);
        ExpressionList itemsList = (ExpressionList) insert.getItemsList();
        for (int i = 0; expressionList != null && i < expressionList.size(); i++) {
            itemsList.addExpressions(expressionList.get(i));
        }
        if (!paramsKeyList.isEmpty()) {
            Matcher questionMarkMatcher = questionMarkPattern.matcher(insert.toString());
            StringBuffer questionReplaceSb = new StringBuffer();
            int i = 0;
            while (questionMarkMatcher.find()) {
                questionMarkMatcher.appendReplacement(questionReplaceSb, "{" + i + "}");
                i++;
            }
            questionMarkMatcher.appendTail(questionReplaceSb);
            sql = questionReplaceSb.toString();
        } else {
            sql = sb.toString();
        }

        return new TemplateReplaceSql(sql, paramsKeyList);
    }

    private Statement preCheck(String sql) throws JSQLParserException {
        //替换参数"{param}"，否则转SQL语法树报错
        Matcher paramsMatcher = paramsPattern.matcher(sql);
        StringBuffer sb = new StringBuffer();
        while (paramsMatcher.find()) {
            paramsMatcher.appendReplacement(sb, "?");
        }
        paramsMatcher.appendTail(sb);
        return CCJSqlParserUtil.parse(sb.toString());
    }

    private boolean checkUpdate(String sql) throws JSQLParserException {
        Statement statement = preCheck(sql);
        if (statement instanceof Update) {
            return true;
        }
        return false;
    }

    private boolean checkDelete(String sql) throws JSQLParserException {
        Statement statement = preCheck(sql);
        if (statement instanceof Delete) {
            return true;
        }
        return false;
    }

    private boolean checkInsert(String sql) throws JSQLParserException {
        Statement statement = preCheck(sql);
        if (statement instanceof Insert) {
            return true;
        }
        return false;
    }

    private boolean checkSelect(String sql) throws JSQLParserException {
        Statement statement = preCheck(sql);
        if (statement instanceof Select) {
            return true;
        }
        return false;
    }

    private static Expression formatStringValue(String value) {
        if (Strings.isNullOrEmpty(value)) {
            return new NullValue();
        } else {
            return new StringValue(value);
        }
    }

    public static class TemplateReplaceSql {

        private String sql;
        private String outputSql;
        private List<ParamKey> paramKeyList;

        public TemplateReplaceSql() {
        }

        public TemplateReplaceSql(String sql, List<ParamKey> paramKeyList) {
            this.sql = sql;
            this.paramKeyList = paramKeyList;
        }

        public TemplateReplaceSql(String sql, String outputSql, List<ParamKey> paramKeyList) {
            this.sql = sql;
            this.outputSql = outputSql;
            this.paramKeyList = paramKeyList;
        }

        public String getSql() {
            return sql;
        }

        public void setSql(String sql) {
            this.sql = sql;
        }

        public String getOutputSql() {
            return outputSql;
        }

        public void setOutputSql(String outputSql) {
            this.outputSql = outputSql;
        }

        public List<ParamKey> getParamKeyList() {
            return paramKeyList;
        }

        public void setParamKeyList(List<ParamKey> paramKeyList) {
            this.paramKeyList = paramKeyList;
        }
    }

    public static class ParamKey {
        private String key;
        private String type;

        public ParamKey(String key, String type) {
            this.key = key;
            this.type = type;
        }

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }
    }

    @Override
    @Async
    public void log(boolean success, String templateId, String entryCode, String entryName, String entryDesc, String outputSql) {
        DynaBean logBean = new DynaBean("JE_CORE_QJSQLLOG", false);
        logBean.set("QJSQLLOG_SUCCESS_CODE", success ? "1" : "2");
        logBean.set("QJSQLLOG_SUCCESS_NAME", success ? "成功" : "失败");
        logBean.set("QJSQLLOG_SQLMBZXRK_CODE", entryCode);
        logBean.set("QJSQLLOG_SUCCESS_NAME", entryName);
        logBean.set("JE_CORE_QJSQL_ID", templateId);
        logBean.set("QJSQLLOG_RKMS", entryDesc);
        logBean.set("QJSQLLOG_ZXSQL", outputSql);
        commonService.buildModelCreateInfo(logBean);
        metaResourceService.insert(logBean);
    }

    public static void main(String[] args) throws JSQLParserException {
        String sql = "SELECT \n" +
                "    JE_CH_TEST1_ID, --主键\n" +
                "    TEST1_NAME,\n" +
                "    TEST1_CODE \n" +
                "FROM \n" +
                "    JE_CH_TEST1 \n" +
                "WHERE \n" +
                "    TEST1_CODE={code};";
        String test = sql.replaceAll("\\--.*", "");
        System.out.println(test);
    }

}
